<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" id="input" />
  </body>
  <script>
    function debounce(fn, delay) {
      console.log("debounce_this", this); // 这里指向window 因为 debounce函数是直接调用的
      var timerId;
      return function () {
        console.log("debounce_return_this", this); // 这里指向input因为，这里并没有产生调用，只是返回了一个函数，这个函数在调用的时候才会执行。
        clearTimeout(timerId);
        var _this = this; // 这里的this指向了真正调用他的input对象
        var args = Array.prototype.slice.call(arguments);
        timerId = setTimeout(function () {
          fn.apply(_this, args); // setTimeout中的this指向window，因此需要使用apply改变this指向。
        }, delay);
      };
    }
    var newHandleInput = debounce(function () {
      console.log("耗时操作", this.value); // this 指向window对象
    }, 1000); // 这个是debounce函数的返回值，并没有产生调用，因此不知道this指向谁。

    var input = document.querySelector("#input");
    input.addEventListener("keyup", newHandleInput); // 这里产生了调用，因此 debounce函数的返回值中的this指向input对象。
  </script>
</html>

<!-- 
1. this 指向 取决于函数是如何调用的。
function () {
  console.log("耗时操作", this.value); // this 指向window对象
} 中有使用到this,这个函数是直接调用的，因此this指向window对象。
但是我们想要让this指向input对象。
因此我们需要在debounce方法的返回中改变this指向。
debounce方法中的this指向在当前情况下指向的是input对象，因此我们可以将
2. 
-->
